<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>MVC、MVP、MVVM比较 | 海晨忆的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
  <meta name="description" content="Android框架的最终目的，也是体现一个项目好坏的唯一标准——高类聚，低耦合">
<meta property="og:type" content="article">
<meta property="og:title" content="MVC、MVP、MVVM比较">
<meta property="og:url" content="https://haichenyi.com/2018/02/22/MVC、MVP、MVVM比较/index.html">
<meta property="og:site_name" content="海晨忆的博客">
<meta property="og:description" content="Android框架的最终目的，也是体现一个项目好坏的唯一标准——高类聚，低耦合">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2018-02-22/mvc流程图.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2018-02-22/MVP流程图.png">
<meta property="og:image" content="https://haichenyi.com/uploads/article/2018-02-22/MVVM流程图.png">
<meta property="og:updated_time" content="2019-09-18T09:10:38.806Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="MVC、MVP、MVVM比较">
<meta name="twitter:description" content="Android框架的最终目的，也是体现一个项目好坏的唯一标准——高类聚，低耦合">
<meta name="twitter:image" content="https://haichenyi.com/uploads/article/2018-02-22/mvc流程图.png">
  
    <link rel="alternate" href="/atom.xml" title="海晨忆的博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/uploads/artistic_image/head.jpg">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/css/highlight.css">
  <script>
  let antiquityStorage = window.sessionStorage.getItem('antiquitySessionStorage');
  if (antiquityStorage == '' || antiquityStorage == null) {
    var antiquityLoader = '<div id="loaderbox"><div class="loader"><div class="load-roll"><div class="load-top"></div><div class="load-right"></div><div class="load-bottom"></div></div></div></div>';
    document.write(antiquityLoader);
    document.body.style.overflow = 'hidden'
  }
  </script>
</head>

<body>
  <div id="fullpage" class="mobile-nav-right">
    
      <div id="wrapper" style="background-image: url(/uploads/artistic_image/bg.jpg)" title="背景图片来自网络">
    
    
      <header id="header">
  <div id="nav-toggle" class="nav-toggle"></div>
  <div class="head-box global-width">
    <nav class="nav-box nav-right">
      
        <a class="nav-item" href="/" title
        
        >首页</a>
      
        <a class="nav-item" href="/archives" title
        
        >归档</a>
      
        <a class="nav-item" href="/about" title
        
        >简历</a>
      
    </nav>
  </div>
</header>
      <div id="middlecontent" title class="global-width sidebar-left">
        <section id="main"><article id="post-MVC、MVP、MVVM比较" class="article global-container article-type-post" itemscope itemprop="blogPost">
  
    <header class="article-header">
      
  
    <h1 class="article-title" itemprop="name">
      MVC、MVP、MVVM比较
    </h1>
  

    </header>
  
  <div class="article-meta">
    <a href="/2018/02/22/MVC、MVP、MVVM比较/" class="article-date">
  <time datetime="2018-02-22T13:43:00.000Z" itemprop="datePublished">2018-02-22</time>
</a>
    
  <div class="article-category">
    <a class="article-category-link" href="/categories/Android-框架/">Android -框架</a>
  </div>

    
  </div>
  
    <span id="busuanzi_container_page_pv">
      本文总阅读量<span id="busuanzi_value_page_pv"></span>次
    </span>
  

  <div class="article-inner">
    
    <div class="article-content article-content-cloud doorframe mac" itemprop="articleBody">
      
        <p>Android框架的最终目的，也是体现一个项目好坏的唯一标准——<strong>高类聚，低耦合</strong></p>
<a id="more"></a>
<h3 id="MVC"><a href="#MVC" class="headerlink" title="MVC"></a>MVC</h3><p>&emsp;&emsp;我们刚接触android写代码的时候基本上都是MVC架构。什么是MVC架构呢？</p>
<p>&emsp;&emsp;MVC：Model View Controller的简称。流程图如下：<br><img src="/uploads/article/2018-02-22/mvc流程图.png" alt="mvc流程图.png"></p>
<p>&emsp;&emsp;当用户发出事件的时候，首先通过V层，通知C层，然后C层通知Model层数据发生了变化，更新数据，M层直接显示数据到V层。</p>
<p>&emsp;&emsp;通俗的讲，xml可以理解层View层，你封装的网络请求的帮助类理解成model层，activity，fragment理解成Controller层。这么理解是可以的，但是，你不能说xml就是view层，这样说是不对的</p>
<p>&emsp;&emsp;举个例子，比方说一个登录的网络请求，首先，你需要点击按钮去触发网络请求的方法，你点击的这个button就是写在xml布局里面的，这就是V层。然后触发的网络请求帮助类去发送对应的登录请求方法，这就是model层。两者是怎么联系在一起的呢？就是我们在activity，fragment层里面写的onclick方法。activity，fragment就是Controller层。</p>
<h3 id="MVP"><a href="#MVP" class="headerlink" title="MVP"></a>MVP</h3><p>&emsp;&emsp;所有的UI变化，网络请求等等业务逻辑之类的都写在Activity里面，Activity既要处理业务逻辑，又要处理UI变化，代码就显得非常臃肿。</p>
<p>&emsp;&emsp;这个时候，MVP就顺势而生，什么是MVP架构呢？</p>
<p>&emsp;&emsp;MVP：Model View Presenter的简称</p>
<p><img src="/uploads/article/2018-02-22/MVP流程图.png" alt="MVP流程图.png"></p>
<p>&emsp;&emsp;MVP作为MVC的演化版本，解决了MVC不少的缺点，对于Android来说，MVP的M层，相对于MVC来说是一样的，而不一样的就是activity不再是controller，而是纯粹的V层，所有关于用户事件的转发，全都由P层去处理</p>
<p>&emsp;&emsp;MVP和MVC最明显的差别就是，M层和V层完全解藕，两者的通信是通过P层，P层作为桥梁，用于操作View层发送的事件到P层，P层去操作M层，并且，讲数据返回给V层。整个过层M层和V层两者完全没有联系。辣么，就有好奇的宝宝就问了，这样做解决不了更本问题，你这样做P层和V层不一样耦合在一起了吗？我们并不能完全不耦合，只是尽可能减少耦合度。我们写程序最终目的就是高类聚，低耦合，不是说完全不耦合。并且，我们这里P层和V层是通过接口通信的，如果网络请求逻辑发生变化，直接修改P层里面的代码，就可以了。V层完全不用改。如果业务逻辑发生变化，我们直接重新定义接口也非常方便</p>
<h3 id="MVVM"><a href="#MVVM" class="headerlink" title="MVVM"></a>MVVM</h3><p>&emsp;&emsp;由微软提出来的—MVVM。什么是MVVM架构呢？</p>
<p>&emsp;&emsp;MVVM：Model View ViewModel</p>
<p><img src="/uploads/article/2018-02-22/MVVM流程图.png" alt="MVVM流程图.png"></p>
<p>&emsp;&emsp;一眼看上去更MVP差不多，只是把P层换成了ViewModel层。还有一点就是View层和ViewModel层是相互绑定的关系，当你更新ViewMdel层数据的时候，View层的UI就要相应的发生变化。</p>
<p>&emsp;&emsp;不管怎么说，三种模式的出现，或者说所有的开发模式，或者说是架构的出现，他们都有一个最终的目的，那就体现是一个项目架构好坏的：<strong>高类聚，低耦合</strong></p>
<p>&emsp;&emsp;学习成本，MVC最简单，弊端也是最多的，学起来也是最快的。MVP和MVVM两者都是MVC的演化版本，两者没法评论优缺点，各有千秋。MVP是目前最火的架构（-.-）。</p>
<h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3><p>&emsp;&emsp;吹了这么多，MVP有没有什么缺点呢？答案是肯定的：有。本人认为，MVP是目前已知框架最好的</p>
<h4 id="缺点"><a href="#缺点" class="headerlink" title="缺点"></a>缺点</h4><ol>
<li><p>P层比较臃肿，所有的逻辑代码，网络请求都丢在P层</p>
</li>
<li><p>接口很多，一个功能，相对于MVC来讲，需要多写很多代码</p>
</li>
<li><p>V层P层耦合度过于高，一旦视图需要变更，P层就要相应的发生变化</p>
</li>
</ol>
<h4 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h4><ol>
<li><p>解藕，这个不用说了</p>
</li>
<li><p>结构清晰明了，不会过了一个月就变成别人的代码</p>
</li>
<li><p>提高了维护性，功能出了问题，直接定位到接口，修改接口就行了</p>
</li>
<li><p>容易进行单元测试，虽然会用单元测试的人比较少</p>
</li>
</ol>

      
    </div>
    
      <footer class="article-footer">
        完
      </footer>
    
  </div>
  
    
<nav id="article-nav">
  <div class="article-nav-block">
    
      <a href="/2018/02/23/从零开始搭建一个主流项目框架（一）—简单的框架/" id="article-nav-newer" class="article-nav-link-wrap">
        <strong class="article-nav-caption"></strong>
        <div class="article-nav-title">
          
            从零开始搭建一个主流项目框架（一）—简单的框架
          
        </div>
      </a>
    
  </div>
  <div class="article-nav-block">
    
      <a href="/2018/02/22/Android事件分发机制原理/" id="article-nav-older" class="article-nav-link-wrap">
        <div class="article-nav-title">Android事件分发机制原理</div>
        <strong class="article-nav-caption"></strong>
      </a>
    
  </div>
</nav>

    
  
  
</article>
</section>
        <aside id="sidebar">
  
    <div class="widget-box">
  <div class="avatar-box avatar-item">
    <img class="avatar" src="/uploads/artistic_image/head.jpg" title="头像来自网络"></img>
    <h3 class="avatar-name">
      
        海晨忆
      
    </h3>
    <p class="avatar-slogan">
      先谋生，再谋爱。人间值得，未来可期。
    </p>
  </div>
</div>


  
    
  <div class="widget-box">
    <h3 class="widget-title">分类</h3>
    <div class="widget">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/Android-Socket/">Android -Socket</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-加密算法/">Android -加密算法</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-常用功能/">Android -常用功能</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-框架/">Android -框架</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-源码解析/">Android -源码解析</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-自定义view/">Android -自定义view</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Android-设计模式/">Android -设计模式</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/JAVA-并发/">JAVA -并发</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Java-SpringBoot/">Java -SpringBoot</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Tomcat/">Tomcat</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/kotlin/">kotlin</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库-JDBC/">数据库 -JDBC</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库-MySQL/">数据库 -MySQL</a></li></ul>
    </div>
  </div>


  
    

  
    
  
    
  <div class="widget-box">
    <h3 class="widget-title">归档</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/07/">July 2021</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/10/">October 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/09/">September 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/07/">July 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/10/">October 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/05/">May 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">March 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/02/">February 2018</a></li></ul>
    </div>
  </div>

  
    
  <div class="widget-box">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2021/07/27/JAVA—公平锁，非公平锁，悲观锁，乐观锁，死锁/">JAVA—公平锁，非公平锁，悲观锁，乐观锁，死锁</a>
          </li>
        
          <li>
            <a href="/2021/07/19/JAVA—线程同步器AQS/">JAVA—线程同步器AQS</a>
          </li>
        
          <li>
            <a href="/2021/07/07/Android模拟点击/">Android模拟点击</a>
          </li>
        
          <li>
            <a href="/2019/11/27/SpringBoot系列-消息-RabbitMQ-（二十）/">SpringBoot系列-消息(RabbitMQ)（二十）</a>
          </li>
        
          <li>
            <a href="/2019/11/13/SpringBoot系列-Docker（十九）/">SpringBoot系列-Docker（十九）</a>
          </li>
        
      </ul>
    </div>
  </div>

  
      <div class="widget-box">
    <h3 class="widget-title">友情链接</h3>
    <div class="widget">
      
        <a class="hrf" style="display: block;" href="https://github.com/haichenyi" title target='_blank'
        >Github</a>
      
        <a class="hrf" style="display: block;" href="https://www.jianshu.com/u/6077ee440c37" title target='_blank'
        >简书</a>
      
        <a class="hrf" style="display: block;" href="https://blog.csdn.net/qq_27634797" title target='_blank'
        >CSDN</a>
      
    </div>
  </div>

  
</aside>
      </div>
      <footer id="footer">
  <div class="foot-box footers global-width">
    &copy;2017-2021 海晨忆 &nbsp;&nbsp;
    <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
    <span id="busuanzi_container_site_pv">阁下是第<span id="busuanzi_value_site_pv"></span>个访客</span>
  </div>
</footer>
      <script src="https://code.jquery.com/jquery-2.0.3.min.js"></script>
<script>
if (!window.jQuery) {
var script = document.createElement('script');
script.src = "/js/jquery-2.0.3.min.js";
document.body.write(script);
}
</script>

  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>



    </div>
    <nav id="mobile-nav" class="mobile-nav-box">
  <div class="mobile-nav-img mobile-nav-top"></div>
  
    <a href="/" class="mobile-nav-link">首页</a>
  
    <a href="/archives" class="mobile-nav-link">归档</a>
  
    <a href="/about" class="mobile-nav-link">简历</a>
  
  <div class="mobile-nav-img  mobile-nav-bottom"></div>
</nav>    
  </div>
</body>
</html>